﻿#region LGPL
/************************************************************************************/
/* Fireball.Windows.Forms a controls library for windows forms
 * 
 * Copyright (C) 2009 Sebastian Faltoni
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the 
 * Free Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 
 * for more details.
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, write to the Free Software Foundation, Inc., 59 
 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
 * 
 * Signature of Sebastian Faltoni, 2 Febbraio 2009
 * Sebastian Faltoni, President of Orangebit
 * 
 ***********************************************************************************/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace Orangebit.Windows.Forms
{

    public enum Orientation
    {
        Horizontal = 0,
        Vertical = 1,
    }
    /// <summary>
    /// The StackPanel control is a control that you should use for adding stacked controls, you can stack
    /// control Vertically or Horizontally by setting the Orientation Property accordingly,
    /// The Children's must be of type StackPanelItem
    /// </summary>
    public class StackPanel : UserControl
    {
        private Orientation orientation = Orientation.Vertical;


        /// <summary>
        /// Get or Set the orientation of the stacked Children's
        /// </summary>
        public Orientation Orientation
        {
            get
            {
                return orientation;
            }
            set
            {
                orientation = value;
                RealignChilds();
            }
        }

        protected override void OnControlAdded(ControlEventArgs e)
        {
            if ((e.Control as StackPanelItem) == null)
            {
                throw new Exception("The added controls is not a StackPanelItem");
            }
            base.OnControlAdded(e);
            RealignChilds();
        }

        protected override void OnParentChanged(EventArgs e)
        {
            base.OnParentChanged(e);

            this.Parent.SizeChanged += new EventHandler(Parent_SizeChanged);
            this.Parent.ClientSizeChanged += new EventHandler(Parent_ClientSizeChanged);
        }

        void Parent_ClientSizeChanged(object sender, EventArgs e)
        {
            RealignChilds();
        }

        void Parent_SizeChanged(object sender, EventArgs e)
        {
            RealignChilds();
        }
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            RealignChilds();
        }

        private void RealignChilds()
        {
            if (this.Orientation == Orientation.Vertical)
            {
                if (this.Parent == null)
                    return;

                if (this.Dock == DockStyle.None)
                {
                    var parentW = this.Parent.ClientSize.Width;
                    var parentH = this.Parent.ClientSize.Height;
                    if (parentW > this.MinimumSize.Width)
                    {
                        this.Width = parentW - this.Margin.Left - this.Margin.Right;
                        //ScrollableControl ctl = this.Parent as ScrollableControl;
                        //if (ctl != null)
                        //{
                        //    if (ctl.VerticalScroll.Visible)
                        //    {
                        //        this.Width -= 10;
                        //    }
                        //}
                    }
                    if (parentH > this.MinimumSize.Height)
                    {
                        this.Height = parentH - this.Margin.Top - this.Margin.Bottom;
                    }
                }
                int currentTop = 0;
                foreach (StackPanelItem child in this.Controls)
                {
                    int left = child.Margin.Left;
                    currentTop += child.Margin.Top;
                    child.Left = left;
                    child.SetWidth(this.Width - child.Margin.Right - left);
                    child.Top = currentTop;
                    currentTop += child.Height + child.Margin.Bottom;
                }
                if (this.Height < currentTop)
                    this.Height = currentTop;
            }
            else
            {
                if (this.Parent == null)
                    return;

                if (this.Dock == DockStyle.None)
                {
                    var parentW = this.Parent.ClientSize.Width;
                    var parentH = this.Parent.ClientSize.Height;
                    if (parentW > this.MinimumSize.Width)
                    {
                        this.Width = parentW - this.Margin.Left - this.Margin.Right;
                    }
                    if (parentH > this.MinimumSize.Height)
                    {
                        this.Height = parentH-1;
                    }
                }

                int currentLeft = 0;
                foreach (StackPanelItem child in this.Controls)
                {
                    int top = child.Margin.Top;
                    currentLeft += child.Margin.Left;
                    child.Left = currentLeft;
                    child.Top = top;
                    if (child.Fit)
                        child.SetHeight(this.Height - child.Margin.Bottom - top-1);
                    currentLeft += child.Width + child.Margin.Right;
                }
                if (this.Width < currentLeft)
                    this.Width = currentLeft;
            }
        }
        public StackPanel()
        {
            this.Margin = new Padding(0);
        }
    }
}
